package com.myopen.controller;


import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.jfinal.aop.Before;
import com.jfinal.core.ActionKey;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.myopen.base.BaseController;
import com.myopen.config.AlipayConfig;
import com.myopen.config.ConstConfig;
import com.myopen.kit.DeviceKit;
import com.myopen.kit.UUIDKit;
import com.myopen.model.Order;


public class AlipayController extends BaseController{

	public static String notify_url="http://"+PropKit.get("app.host")+"/alipay/notify";
	public static String return_url="http://"+PropKit.get("app.host")+"/paySuccess";

	
	@ActionKey("/alipay")
	public void alipay(){
		
		if(!DeviceKit.isMobileDevice(getRequest())){
			forwardAction("/alipay/web");
		}else{
			forwardAction("/alipay/wap");
		}
	}

	@ActionKey("/alipay/wap")
	public void alipay_wap(){

		String orderId=getPara("orderId");
		Record order=Order.dao.getRecordById(orderId);

		Double amount=order.getDouble("amount");

		// 商户订单号，商户网站订单系统中唯一订单号，必填
		String out_trade_no = order.getStr("number");
		// 订单名称，必填
		String subject = "测试订单";
		// 付款金额，必填
		String total_amount=amount.toString();
		// 商品描述，可空
		String body = "";
		// 超时时间 可空
	    String timeout_express="10m";//10分钟应该，不确定是
		// 销售产品码 必填
		String product_code="QUICK_WAP_WAY";
		/**********************/
		// SDK 公共请求类，包含公共请求参数，以及封装了签名与验签，开发者无需关注签名与验签     
		//调用RSA签名方式
		AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);
		AlipayTradeWapPayRequest alipay_request = new AlipayTradeWapPayRequest();
		
		// 封装请求支付信息
		AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
		model.setOutTradeNo(out_trade_no);
		model.setSubject(subject);
		model.setTotalAmount(total_amount);
		model.setBody(body);
		model.setTimeoutExpress(timeout_express);
		model.setProductCode(product_code);
		alipay_request.setBizModel(model);
		// 设置异步通知地址
		alipay_request.setNotifyUrl(notify_url);
		// 设置同步地址
		alipay_request.setReturnUrl(return_url);  
		// form表单生产
		String form = "";
		try {
			Order.dao.createPayHistory(orderId, out_trade_no, amount, ConstConfig.pay_alipay, product_code);
			client.pageExecute(alipay_request).getOutTradeNo();
			// 调用SDK生成表单
			form = client.pageExecute(alipay_request).getBody();
		} catch (AlipayApiException e) {
			e.printStackTrace();
		} 

		renderHtml(form);
	}

	@ActionKey("/alipay/web")
	public void alipay_web(){

		String orderId=getPara("orderId");
		Record order=Order.dao.getRecordById(orderId);

		Double amount=order.getDouble("amount");

		// 商户订单号，商户网站订单系统中唯一订单号，必填
		String out_trade_no = order.getStr("number");
		System.out.println(out_trade_no);
		// 订单名称，必填
		String subject = "测试订单";
		// 付款金额，必填
		String total_amount=amount.toString();
		// 商品描述，可空
		String body = "";
		// 超时时间 可空
	    String timeout_express="10m";//10分钟应该，不确定是
		// 销售产品码 必填
		String product_code="FAST_INSTANT_TRADE_PAY";
		/**********************/
		// SDK 公共请求类，包含公共请求参数，以及封装了签名与验签，开发者无需关注签名与验签     
		//调用RSA签名方式
		AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);
		AlipayTradePagePayRequest alipay_request=new AlipayTradePagePayRequest();
		// 封装请求支付信息
		AlipayTradePagePayModel model=new AlipayTradePagePayModel();
		model.setOutTradeNo(out_trade_no);
		model.setSubject(subject);
		model.setTotalAmount(total_amount);
		model.setBody(body);
		model.setTimeoutExpress(timeout_express);
		model.setProductCode(product_code);
		alipay_request.setBizModel(model);
		// 设置异步通知地址
		alipay_request.setNotifyUrl(notify_url);
		// 设置同步地址
		alipay_request.setReturnUrl(return_url);  
		// form表单生产
		String form = "";
		try {
			Order.dao.createPayHistory(orderId, out_trade_no, amount, ConstConfig.pay_alipay, product_code);
			client.pageExecute(alipay_request).getOutTradeNo();
			// 调用SDK生成表单
			form = client.pageExecute(alipay_request).getBody();
		} catch (AlipayApiException e) {
			e.printStackTrace();
		} 

		renderHtml(form);
	}



	@ActionKey("/alipay/notify")
	@Before(Tx.class)
	public void alipay_notify(){

		//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
		
		Map<String,String> params = new HashMap<String,String>();
		Map requestParams = getParaMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i]
						: valueStr + values[i] + ",";
			}
			//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
			params.put(name, valueStr);
		}

		//商户订单号
		String out_trade_no = getPara("out_trade_no");
		
		//支付宝交易号
		String trade_no = getPara("trade_no");
		
		//交易状态
		String trade_status=getPara("trade_status");

		//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
		//计算得出通知验证结果
		//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
		boolean verify_result = true;

		System.out.println(out_trade_no);

		try {
			verify_result=AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		
		if(verify_result){//验证成功
			//////////////////////////////////////////////////////////////////////////////////////////
			//请在这里加上商户的业务逻辑程序代码

			//——请根据您的业务逻辑来编写程序（以下代码仅作参考）——

			Record payHistory=Order.dao.getPayHistory(out_trade_no);
			System.out.println("======trade_status"+trade_status);
			//待支付状态
			if(trade_status.equals("TRADE_FINISHED")){
				//判断该笔订单是否在商户网站中已经做过处理
					//如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
					//请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
					//如果有做过处理，不执行商户的业务程序
					
				//注意：
				//如果签约的是可退款协议，退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
				//如果没有签约可退款协议，那么付款完成后，支付宝系统发送该交易状态通知。
				//Order.dao.successPayHistory(ConstConfig.pay_alipay, trade_no);//会同时修改订单状态

				//System.out.println("支付宝订单处理完成");
				//Order.dao.successPayHistory(ConstConfig.pay_alipay, trade_no);//会同时修改订单状态

				if("0".equals(payHistory.getStr("payStatus"))){
					//待支付，可以支付
					System.out.println("支付宝订单处理成功");
					Order.dao.completePayHistory(out_trade_no,trade_no);//会同时修改订单状态
				}
				
				renderText("success");
			} else if (trade_status.equals("TRADE_SUCCESS")){
				//判断该笔订单是否在商户网站中已经做过处理
					//如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
					//请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
					//如果有做过处理，不执行商户的业务程序
					
				//注意：
				//如果签约的是可退款协议，那么付款完成后，支付宝系统发送该交易状态通知。

				if("0".equals(payHistory.getStr("payStatus"))){
					//待支付，可以支付
					System.out.println("支付宝订单处理成功");
					Order.dao.successPayHistory(out_trade_no,trade_no);//会同时修改订单状态
				}
				
			}
			

			//——请根据您的业务逻辑来编写程序（以上代码仅作参考）——
			//out.clear();
			//out.println("success");	//请不要修改或删除

			//////////////////////////////////////////////////////////////////////////////////////////

			renderText("success");
		}else{//验证失败
			renderText("fail");
		}

		

	}

	@ActionKey("/alipay/return")
	public void alipay_return(){
		
		Map<String,String> params = new HashMap<String,String>();
		Map<String,String[]> requestParams = getRequest().getParameterMap();
		for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i]
						: valueStr + values[i] + ",";
			}
			params.put(name, valueStr);
		}
		
		boolean verify_result = true;

		try {
			verify_result=AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}


		//——请在这里编写您的程序（以下代码仅作参考）——
		if(verify_result) {
			//商户订单号
			String out_trade_no = getPara("out_trade_no");
			//支付宝交易号
			String trade_no = getPara("trade_no");
			//付款金额
			String total_amount = getPara("total_amount");
			
		}

		forwardAction("/paySuccess");

	}

	public Map<String,Object> alipay_refund(String orderId){

		Record orderPayHis=Order.dao.getPayHistorySuccessByOrderId(orderId);

		//获得初始化的AlipayClient
		AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
			
		//设置请求参数
		AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();

		AlipayTradeRefundModel model=new AlipayTradeRefundModel();

		//商户订单号，商户网站订单系统中唯一订单号
		String out_trade_no = orderPayHis.getStr("out_trade_no");
		//支付宝交易号
		String trade_no = orderPayHis.getStr("trade_no");
		//请二选一设置
		//需要退款的金额，该金额不能大于订单金额，必填
		String refund_amount = orderPayHis.get("amount").toString();
		//退款的原因说明
		String refund_reason = "退款";
		//标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传
		String out_request_no =out_trade_no+"_"+UUIDKit.getUUID();

		model.setOutTradeNo(out_trade_no);
		model.setTradeNo(trade_no);
		model.setRefundAmount(refund_amount);
		model.setRefundReason(refund_reason);
		model.setOutRequestNo(out_request_no);

		alipayRequest.setBizModel(model);

		//请求
		String result=null;
		try {
			result = alipayClient.execute(alipayRequest).getBody();
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}

		return (Map<String,Object>)JSON.parse(result);

	}



}
